package com.wksc.framework.impexp.util;

import com.wksc.framework.impexp.bean.ImportService;
import com.wksc.framework.impexp.constants.IEConstants;
import com.wksc.framework.impexp.dao.Data2FileDao;
import com.wksc.framework.impexp.dao.ImpExpDao;
import com.wksc.framework.impexp.i18n.MessageI18nImpExp;
import com.wksc.framework.impexp.log.ImpExpLog;
import com.wksc.framework.impexp.mode.Mode;
import com.wksc.framework.impexp.writer.Writer;
import com.wksc.framework.impexp.writer.XlsWriter;

import java.lang.reflect.Constructor;


/**
 * 获取外部配置的类的实例
 *
 * @author QinJinxue
 * @daDec 23, 2010
 * @since 1.0
 */
public class ClassFactory {
    /**
     * 国际化文字处理类
     */
    private static MessageI18nImpExp i18n;
    /**
     * 业务代码工程与impExp工程间的数据通道接口
     */
    private static OutInterfaceImpExp outInterface;

    /**
     * 获取导入业务处理代码补全类的实例
     *
     * @param classStr
     * @return
     * @author QinJinxue
     */
    public static ImportService getService(String classStr) {
        try {
            Object obj = ClassFactory.get(classStr,
                    com.wksc.framework.impexp.bean.ImportService.class, null, null);
            return obj == null ? null : (ImportService) obj;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取日志类实例
     *
     * @return
     * @author QinJinxue
     */
    public static ImpExpLog getLog(Class<?> clas) {
        //		LogConfig.setConfigEnvName(getConfigEnvName()); //设置日志组件加载环境变量路径
//		if (LogConfig.isLogByLog4j()) {
//			return BaseLoggerLog4J.logFactory(clazz);
//		}
//		return new BaseLogger(clazz);
        try {
            Object obj = ClassFactory.get(SysParam.getLogStr(),
                    ImpExpLog.class,
                    new Class[]{Class.class}, new Object[]{clas});
            return obj == null ? null : (ImpExpLog) obj;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取导出查询数据类实例
     *
     * @return
     * @author QinJinxue
     */
    public static Data2FileDao getData2FileDao() {
        try {
            Object obj = ClassFactory.get(SysParam.getData2FileDaoStr(),
                    Data2FileDao.class, null, null);
            return obj == null ? null : (Data2FileDao) obj;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取导入导出操作日志表的类
     *
     * @return
     * @author QinJinxue
     */
    public static ImpExpDao getImpExpDao() {
        try {
            Object obj = ClassFactory.get(SysParam.getLogTableStr(),
                    com.wksc.framework.impexp.dao.ImpExpDao.class, null, null);
            return obj == null ? null : (ImpExpDao) obj;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 方法描述：获取导出模式
     *
     * @return
     * @creator wanglei
     */
    public static Mode getExpMode() {
        switch (IEConstants.EXP_MODE) {
            case 0:
                return Mode.EXP_CLASSIC;
            case 1:
                return Mode.EXP_CSV;
            case 2:
                return Mode.EXP_CSV;
            case 3:
                return Mode.EXP_TXT;
            default:
                return Mode.EXP_CLASSIC;
        }
    }

    /**
     * 方法描述：获取导入模式
     *
     * @return
     * @creator wanglei
     */
    public static Mode getImpMode() {
        switch (IEConstants.IMP_MODE) {
            case 0:
                return Mode.IMP_XLS;
            case 1: //csv格式在C13版本中未使用,为兼容以前版本特保留CSV模式 20111201 wanglei
                return Mode.IMP_XLS;
//			return Mode.IMP_CSV; //如需启用CSV格式导入则去掉此行注释并注释掉上行代码
            default:
                return Mode.IMP_XLS;
        }
    }

    /**
     * 获取导出报表格式的类
     *
     * @param excelConflate
     * @return
     * @author QinJinxue
     */
    public static Writer getGridViewWrite(Object excelConflate) {
        try {
            Object obj = ClassFactory.get(SysParam.getGridViewWrite(),
                    com.wksc.framework.impexp.writer.Writer.class,
                    null, null);
            if (null != obj) {
                ((XlsWriter) obj).setObjExcelConflate(excelConflate);
            }
            return obj == null ? null : (Writer) obj;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取国际化文字处理类
     *
     * @return MessageI18nImpExp实现类的实例
     * @author zhangyan
     */
    public static MessageI18nImpExp getI18n() {
        try {
            if (null == i18n) {
                Object obj = ClassFactory.get(SysParam.getI18nImplClass(),
                        MessageI18nImpExp.class, null, null);
                return obj == null ? null : (MessageI18nImpExp) obj;
            }
            return i18n;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 业务代码工程与impExp工程间的数据通道接口处理类
     *
     * @return OutInterfaceImpExp实现类的实例
     * @author zhangyan
     */
    public static OutInterfaceImpExp getOutInterface() {
        try {
            if (null == outInterface) {
                outInterface = (OutInterfaceImpExp) ClassFactory
                        .get("com.huawei.comm.impexp.inter.OutInterfaceImpExpImpl",
                                OutInterfaceImpExp.class, null, null);
                return outInterface == null ? null : outInterface;
            }
            return outInterface;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 通过一个字符串获取类的实例
     *
     * @param classStr       通过该字符串来获取实例
     * @param compareClass   判断是否是该接口的类型,为null时不比较
     * @param parameterTypes 获取带参构造方法的参数类型列表,无参时传null
     * @param parameter      获取带参构造方法的参数列表,无参时传null
     * @return 指定类的实例
     * @author QinJinxue
     */
    private static Object get(String classStr, Class<?> compareClass,
                              Class<?>[] parameterTypes, Object[] parameter) {
        Object object = null;
        try {
            Class<?> clas = Class.forName(classStr);
            Constructor<?> constructor = clas
                    .getDeclaredConstructor(parameterTypes);
            constructor.setAccessible(true);
            object = constructor.newInstance(parameter);
            if (null != compareClass && !compareClass.isInstance(object)) {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return object;
    }
}
